<template>
  <div ref="boxRef" class="chart-box gauge-box">
    <div class="chart-header">
      <h3>
        <span class="title-icon">|</span>
        <span>库存和销量分析</span>
      </h3>
      <button class="fullscreen-btn" @click="toggleFullscreen">⛶</button>
    </div>
    <div ref="chartRef" class="chart"></div>
    <div v-if="totalPages > 1" class="gauge-pagination">
      <span
        v-for="index in totalPages"
        :key="index"
        class="page-dot"
        :class="{ active: index - 1 === pageIndex }"
      ></span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue';
import * as echarts from 'echarts';
import { subscribeToChart } from '@/services/dataHub';

const props = defineProps<{ isDarkTheme: boolean }>();

const chartRef = ref<HTMLElement | null>(null);
const boxRef = ref<HTMLElement | null>(null);
let chart: echarts.ECharts | null = null;
let resizeHandler: (() => void) | null = null;
let fullscreenTimer: number | null = null;
let pageTimer: number | null = null;
let unsubscribe: (() => void) | null = null;
const PAGE_INTERVAL = 5000;

type StockItem = {
  name: string;
  stock: number;
  sales: number;
};

let originalData: StockItem[] = [];
const pageIndex = ref(0);
const totalPages = ref(0);

const decodeText = (text: string) => {
  try {
    return decodeURIComponent(escape(text));
  } catch (error) {
    return text;
  }
};

const stopPageLoop = () => {
  if (pageTimer) {
    window.clearInterval(pageTimer);
    pageTimer = null;
  }
};

const startPageLoop = () => {
  stopPageLoop();
  // console.log('[GaugeChart] startPageLoop - totalPages:', totalPages.value, 'pageIndex:', pageIndex.value);
  if (totalPages.value <= 1) {
    // console.log('[GaugeChart] 分页数不足，不启动轮播');
    return;
  }
  pageTimer = window.setInterval(() => {
    pageIndex.value = (pageIndex.value + 1) % totalPages.value;
    // console.log('[GaugeChart] 翻页到:', pageIndex.value);
    updateChartOption();
  }, PAGE_INTERVAL);
  // console.log('[GaugeChart] 轮播定时器已启动，间隔:', PAGE_INTERVAL);
};

const getPagedItems = () => {
  if (!originalData.length) {
    totalPages.value = 0;
    return [] as StockItem[];
  }

  totalPages.value = Math.max(1, Math.ceil(originalData.length / PAGE_SIZE));
  // console.log('[GaugeChart] getPagedItems - 数据总数:', originalData.length, '页大小:', PAGE_SIZE, '总页数:', totalPages.value, '当前页:', pageIndex.value);
  if (pageIndex.value >= totalPages.value) {
    pageIndex.value = 0;
  }

  const start = pageIndex.value * PAGE_SIZE;
  return originalData.slice(start, start + PAGE_SIZE);
};

type GaugeGradientStop = { offset: number; color: string };
type GaugeLayout = { center: [string, string]; gradient: GaugeGradientStop[] };

const GAUGE_LAYOUTS: GaugeLayout[] = [
  {
    center: ['17%', '33%'],
    gradient: [
      { offset: 0, color: '#c8f9db' },
      { offset: 0.7, color: '#6be38e' },
      { offset: 1, color: '#208b4f' },
    ],
  },
  {
    center: ['50%', '33%'],
    gradient: [
      { offset: 0, color: '#c4ddff' },
      { offset: 0.65, color: '#5fa8ff' },
      { offset: 1, color: '#1c64f2' },
    ],
  },
  {
    center: ['83%', '33%'],
    gradient: [
      { offset: 0, color: '#ffd0d0' },
      { offset: 0.6, color: '#ff7a7a' },
      { offset: 1, color: '#dc2626' },
    ],
  },
  {
    center: ['32%', '70%'],
    gradient: [
      { offset: 0, color: '#ffe5c2' },
      { offset: 0.65, color: '#ffad5a' },
      { offset: 1, color: '#ea580c' },
    ],
  },
  {
    center: ['67%', '70%'],
    gradient: [
      { offset: 0, color: '#b8f9f1' },
      { offset: 0.6, color: '#52e0ce' },
      { offset: 1, color: '#0f9a8a' },
    ],
  },
];
const PAGE_SIZE = GAUGE_LAYOUTS.length;

const disposeChart = () => {
  stopPageLoop();
  if (chart && !chart.isDisposed()) {
    chart.dispose();
  }
  chart = null;
};

// 获取库存销量数据（改用 WebSocket）
function setupStockDataSubscription() {
  unsubscribe = subscribeToChart('stock', (data: any) => {
    const list: StockItem[] = Array.isArray(data)
      ? data
      : Array.isArray(data?.data)
        ? data.data
        : [];

    const mapped = list
      .map((item) => ({
        name: decodeText(item.name),
        stock: Number(item.stock) || 0,
        sales: Number(item.sales) || 0,
      }))
      .filter((item) => item.name);

    mapped.sort((a, b) => b.sales - a.sales);
    // 只在数据长度变化时重置 pageIndex
    const oldLen = originalData.length;
    originalData = mapped;
    if (oldLen !== mapped.length) {
      pageIndex.value = 0;
    }
    updateChartOption();
  });
}


// 更新图表配置
function updateChartOption() {
  if (!chart) return;

  const items = getPagedItems();

  if (!items.length) {
    chart.setOption({
      backgroundColor: 'transparent',
      series: [],
    });
    stopPageLoop();
    return;
  }

  const baseAxisLine = {
    lineStyle: {
      width: 10,
      color: [[1, '#1f2937']] as [number, string][],
    },
  };

  const baseProgress = {
    show: true,
    width: 10,
    roundCap: true,
  };

  const seriesData = items.map((item, index) => {
    const layout = (GAUGE_LAYOUTS[index] ?? GAUGE_LAYOUTS[GAUGE_LAYOUTS.length - 1]) as GaugeLayout;
    const maxValue = Math.max(item.stock, item.sales, 1);
    const gradient = new echarts.graphic.LinearGradient(0, 0, 1, 1, layout.gradient);

    return {
      type: 'gauge',
      center: layout.center,
      radius: '35%',
      startAngle: 90,
      endAngle: -270,
      min: 0,
      max: Math.ceil(maxValue * 1.2),
      progress: {
        ...baseProgress,
        itemStyle: { color: gradient },
      },
      axisLine: baseAxisLine,
      axisTick: { show: false },
      splitLine: { show: false },
      axisLabel: { show: false },
      pointer: { show: false },
      title: {
        show: false,
      },
      detail: {
        valueAnimation: true,
        offsetCenter: [0, '5%'],
        fontSize: 18,
        rich: {
          value: {
            fontSize: 18,
            color: '#ffffff',
            fontWeight: 700,
            lineHeight: 28,
          },
          name: {
            fontSize: 11,
            color: '#a0aec0',
            lineHeight: 20,
          },
        },
        formatter: () => `{value|${Math.round(item.sales)}}\n{name|${item.name}}`,
      },
      data: [{ value: item.sales, name: item.name }],
    };
  });

  const option = {
    backgroundColor: 'transparent',
    tooltip: {
      trigger: 'item',
      formatter: (params: any) => {
        const seriesIndex = params?.seriesIndex ?? 0;
        const item = items[seriesIndex];
        if (!item) return '';
        return `${item.name}<br/>销量：${item.sales}<br/>库存：${item.stock}`;
      },
    },
    series: seriesData,
  } as echarts.EChartsCoreOption;

  chart.setOption(option, true);
  // 只在轮播定时器不存在时启动（避免重复启动导致定时器失效）
  if (!pageTimer && totalPages.value > 1) {
    startPageLoop();
  }
}

const initChart = () => {
  if (!chartRef.value) return;
  disposeChart();
  chart = echarts.init(chartRef.value);

  if (originalData.length) {
    updateChartOption();
  }

  if (!resizeHandler) {
    resizeHandler = () => chart?.resize();
    window.addEventListener('resize', resizeHandler);
  }
};

const toggleFullscreen = () => {
  const box = boxRef.value;
  if (!box) return;
  const button = box.querySelector('.fullscreen-btn') as HTMLButtonElement | null;

  if (!box.classList.contains('fullscreen')) {
    box.classList.add('fullscreen');
    if (button) button.textContent = '✕';
    fullscreenTimer = window.setTimeout(() => chart?.resize(), 300);
    window.addEventListener('keydown', escListener);
  } else {
    box.classList.remove('fullscreen');
    if (button) button.textContent = '⛶';
    fullscreenTimer = window.setTimeout(() => chart?.resize(), 300);
    window.removeEventListener('keydown', escListener);
  }
};

function escListener(e: KeyboardEvent) {
  if (e.key === 'Escape') {
    const box = boxRef.value;
    if (box && box.classList.contains('fullscreen')) {
      toggleFullscreen();
    }
  }
}

watch(
  () => props.isDarkTheme,
  () => {
    initChart();
  }
);

onMounted(() => {
  setupStockDataSubscription();
  initChart();
});

onUnmounted(() => {
  if (unsubscribe) {
    unsubscribe();
  }
  if (resizeHandler) {
    window.removeEventListener('resize', resizeHandler);
  }
  if (fullscreenTimer) {
    window.clearTimeout(fullscreenTimer);
  }
  window.removeEventListener('keydown', escListener);
  disposeChart();
});
</script>

<style scoped>
.gauge-pagination {
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
}

.page-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(132, 146, 166, 0.35);
  transition: all 0.3s ease;
}

.page-dot.active {
  background: #4a9eff;
  box-shadow: 0 0 8px rgba(74, 158, 255, 0.6);
  transform: scale(1.2);
}
</style>
